]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
[StWidget] add list-like methods for style_class and pseudo_class
authorDan Winship <danw@gnome.org>
Fri, 19 Mar 2010 15:37:04 +0000 (11:37 -0400)
committerDan Winship <danw@gnome.org>
Wed, 24 Mar 2010 13:40:37 +0000 (09:40 -0400)
Since style_class and pseudo_class are space-separated lists of names,
add new methods to add and remove individual names rather than just
re-setting the entire name.

Update existing code to use the new pseudo-class methods where
appropriate. In some cases, this may result in actors having multiple
pseudoclasses where previously they only had one at a time, but there
don't seem to be any visible differences.

(There are some places that could usefully use the new style_class
methods as well, but this patch doesn't change them.)

Also, update test-theme.c to test the new methods.

https://bugzilla.gnome.org/show_bug.cgi?id=604943

14 files changed:
js/ui/appDisplay.js
js/ui/dash.js
js/ui/genericDisplay.js
js/ui/lookingGlass.js
js/ui/workspacesView.js
src/Makefile-st.am
src/st/st-button.c
src/st/st-clickable.c
src/st/st-entry.c
src/st/st-scroll-bar.c
src/st/st-widget.c
src/st/st-widget.h
src/st/test-theme.c
src/st/test-theme.css

index ab06c3549b2b35f1eedb2629a40967346ecbbba6..9ec427f1af239198956c5b8053efc5e26ab55228 100644 (file)
@@ -797,12 +797,12 @@ AppIconMenu.prototype = {
 
     _updateHighlight: function (item) {
         if (this._highlightedItem) {
-            this._highlightedItem.set_style_pseudo_class(null);
+            this._highlightedItem.remove_style_pseudo_class('hover');
             this.emit('highlight-window', null);
         }
         this._highlightedItem = item;
         if (this._highlightedItem) {
-            item.set_style_pseudo_class('hover');
+            item.add_style_pseudo_class('hover');
             let window = this._highlightedItem._window;
             if (window)
                 this.emit('highlight-window', window);
index e36bd2d95a0f70c48bfb36d8fa744f81eb3eb9f9..3d5ab4aef0728b55a49c7c3468e178b1e13f302b 100644 (file)
@@ -359,7 +359,10 @@ SearchResult.prototype = {
     },
 
     setSelected: function(selected) {
-        this._content.set_style_pseudo_class(selected ? 'selected' : null);
+        if (selected)
+            this._content.add_style_pseudo_class('selected');
+        else
+            this._content.remove_style_pseudo_class('selected');
     },
 
     activate: function() {
@@ -630,10 +633,10 @@ MoreLink.prototype = {
     setPane: function (pane) {
         this._pane = pane;
         this._pane.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
-            if (!isOpen)
-                this._expander.style_class = 'more-link-expander';
+            if (isOpen)
+                this._expander.add_style_class_name('open');
             else
-                this._expander.style_class = 'more-link-expander open';
+                this._expander.remove_style_class_name('open');
         }));
     }
 };
index 102c681b47b5ce03d986d57196d9af79abfcdc19..219e92c174e1b90e27ff039775ce89c76c6c9ed5 100644 (file)
@@ -105,7 +105,10 @@ GenericDisplayItem.prototype = {
     // Highlights the item by setting a different background color than the default 
     // if isSelected is true, removes the highlighting otherwise.
     markSelected: function(isSelected) {
-        this.actor.set_style_pseudo_class(isSelected ? "selected" : null);
+        if (iSelected)
+            this.actor.add_style_pseudo_class('selected');
+        else
+            this.actor.remove_style_pseudo_class('selected');
     },
 
     /*
index c5d5051c5b0a222b3665ad7ae5b1846ab7fe2c92..89c9f3e8a926104568c9b6138f7b8c10ae3b8a39 100644 (file)
@@ -84,7 +84,7 @@ Notebook.prototype = {
         if (this._selectedIndex < 0)
             return;
         let tabData = this._tabs[this._selectedIndex];
-        tabData.labelBox.set_style_pseudo_class(null);
+        tabData.labelBox.remove_style_pseudo_class('selected');
         tabData.scrollView.hide();
         this._selectedIndex = -1;
     },
@@ -98,7 +98,7 @@ Notebook.prototype = {
             return;
         }
         let tabData = this._tabs[index];
-        tabData.labelBox.set_style_pseudo_class('selected');
+        tabData.labelBox.add_style_pseudo_class('selected');
         tabData.scrollView.show();
         this._selectedIndex = index;
         this.emit('selection', tabData.child);
index 47886b99ef79a9f3ed022b3f9604c9f78051b092..5712509e3ad3cfad726d80b582b564fbfa1aca49 100644 (file)
@@ -484,7 +484,10 @@ NewWorkspaceArea.prototype = {
     },
 
     setStyle: function(isHover) {
-        this._child1.set_style_pseudo_class(isHover ? 'hover' : null);
+        if (isHover)
+            this._child1.add_style_pseudo_class('hover');
+        else
+            this._child1.remove_style_pseudo_class('hover');
     }
 };
 
index 51593e24075aed159ca2d66b4fc5aa9e9b9fd45d..706c5884051c0b0bf016611b56d5799f8bd185a7 100644 (file)
@@ -161,6 +161,6 @@ libst_1_0_la_LDFLAGS = $(LDADD)
 noinst_PROGRAMS += test-theme
 
 test_theme_CPPFLAGS = $(st_cflags)
-test_theme_LDADD = libst-1.0.la
+test_theme_LDADD = libst-1.0.la libbig-1.0.la
 
 test_theme_SOURCES = st/test-theme.c
index ae53021ecc0a40fc963e45f712e0ce681bd7244e..2b8d7574ebde0c86647d804557dd8c21de713cbe 100644 (file)
@@ -133,21 +133,13 @@ st_button_style_changed (StWidget *widget)
 static void
 st_button_real_pressed (StButton *button)
 {
-  st_widget_set_style_pseudo_class ((StWidget*) button, "active");
+  st_widget_add_style_pseudo_class ((StWidget*) button, "active");
 }
 
 static void
 st_button_real_released (StButton *button)
 {
-  StButtonPrivate *priv = button->priv;
-
-  if (priv->is_checked)
-    st_widget_set_style_pseudo_class ((StWidget*) button, "checked");
-  else if (!priv->is_hover)
-    st_widget_set_style_pseudo_class ((StWidget*) button, NULL);
-  else
-    st_widget_set_style_pseudo_class ((StWidget*) button, "hover");
-
+  st_widget_remove_style_pseudo_class ((StWidget*) button, "active");
 }
 
 static gboolean
@@ -212,8 +204,7 @@ st_button_enter (ClutterActor         *actor,
 {
   StButton *button = ST_BUTTON (actor);
 
-  if (!button->priv->is_checked)
-    st_widget_set_style_pseudo_class ((StWidget*) button, "hover");
+  st_widget_add_style_pseudo_class ((StWidget*) button, "hover");
 
   button->priv->is_hover = 1;
 
@@ -240,10 +231,7 @@ st_button_leave (ClutterActor         *actor,
         klass->released (button);
     }
 
-  if (button->priv->is_checked)
-    st_widget_set_style_pseudo_class ((StWidget*) button, "checked");
-  else
-    st_widget_set_style_pseudo_class ((StWidget*) button, NULL);
+  st_widget_remove_style_pseudo_class ((StWidget*) button, "hover");
 
   return CLUTTER_ACTOR_CLASS (st_button_parent_class)->leave_event (actor, event);
 }
@@ -558,12 +546,9 @@ st_button_set_checked (StButton *button,
       button->priv->is_checked = checked;
 
       if (checked)
-        st_widget_set_style_pseudo_class ((StWidget*) button, "checked");
-      else
-      if (button->priv->is_hover)
-        st_widget_set_style_pseudo_class ((StWidget*) button, "hover");
+        st_widget_add_style_pseudo_class ((StWidget*) button, "checked");
       else
-        st_widget_set_style_pseudo_class ((StWidget*) button, NULL);
+        st_widget_remove_style_pseudo_class ((StWidget*) button, "checked");
     }
 
   g_object_notify (G_OBJECT (button), "checked");
index bc5ad49949d45b74fe2794d5cfbec39efcd772b1..ee52e3738b46e55e1cb8da1b9675143ded00207c 100644 (file)
@@ -42,9 +42,15 @@ static guint st_clickable_signals [LAST_SIGNAL] = { 0 };
 static void
 sync_pseudo_class (StClickable *self)
 {
-  st_widget_set_style_pseudo_class (ST_WIDGET (self),
-                                    (self->priv->pressed || self->priv->active) ? "pressed" :
-                                      (self->priv->hover ? "hover" : NULL));
+  if (self->priv->pressed || self->priv->active)
+    st_widget_add_style_pseudo_class (ST_WIDGET (self), "pressed");
+  else
+    st_widget_remove_style_pseudo_class (ST_WIDGET (self), "pressed");
+
+  if (self->priv->hover)
+    st_widget_add_style_pseudo_class (ST_WIDGET (self), "hover");
+  else
+    st_widget_remove_style_pseudo_class (ST_WIDGET (self), "hover");
 }
 
 static void
index 147640d7edf863fac0288a6c6d8214b41e272dd8..c7831799689a964efa38ae4d5d3f41de4f0a8212 100644 (file)
@@ -391,7 +391,8 @@ clutter_text_focus_in_cb (ClutterText  *text,
 
       clutter_text_set_text (text, "");
     }
-  st_widget_set_style_pseudo_class (ST_WIDGET (actor), "focus");
+  st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "indeterminate");
+  st_widget_add_style_pseudo_class (ST_WIDGET (actor), "focus");
   clutter_text_set_cursor_visible (text, TRUE);
 }
 
@@ -401,17 +402,15 @@ clutter_text_focus_out_cb (ClutterText  *text,
 {
   StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
 
+  st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "focus");
+
   /* add a hint if the entry is empty */
   if (priv->hint && !strcmp (clutter_text_get_text (text), ""))
     {
       priv->hint_visible = TRUE;
 
       clutter_text_set_text (text, priv->hint);
-      st_widget_set_style_pseudo_class (ST_WIDGET (actor), "indeterminate");
-    }
-  else
-    {
-      st_widget_set_style_pseudo_class (ST_WIDGET (actor), NULL);
+      st_widget_add_style_pseudo_class (ST_WIDGET (actor), "indeterminate");
     }
   clutter_text_set_cursor_visible (text, FALSE);
 }
@@ -586,7 +585,7 @@ st_entry_enter_event (ClutterActor         *actor,
 
   if (priv->hint && priv->hint_visible)
     {
-      st_widget_set_style_pseudo_class (ST_WIDGET (actor), "hover");
+      st_widget_add_style_pseudo_class (ST_WIDGET (actor), "hover");
     }
 
   return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->enter_event (actor, event);
@@ -596,16 +595,7 @@ static gboolean
 st_entry_leave_event (ClutterActor         *actor,
                       ClutterCrossingEvent *event)
 {
-  StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
-
-  if (priv->hint && priv->hint_visible)
-    {
-      st_widget_set_style_pseudo_class (ST_WIDGET (actor), "indeterminate");
-    }
-  else
-    {
-      st_widget_set_style_pseudo_class (ST_WIDGET (actor), "focus");
-    }
+  st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "hover");
 
   return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->leave_event (actor, event);
 }
@@ -782,14 +772,11 @@ st_entry_set_text (StEntry     *entry,
     {
       text = priv->hint;
       priv->hint_visible = TRUE;
-      st_widget_set_style_pseudo_class (ST_WIDGET (entry), "indeterminate");
+      st_widget_add_style_pseudo_class (ST_WIDGET (entry), "indeterminate");
     }
   else
     {
-      if (HAS_FOCUS (priv->entry))
-        st_widget_set_style_pseudo_class (ST_WIDGET (entry), "focus");
-      else
-        st_widget_set_style_pseudo_class (ST_WIDGET (entry), NULL);
+      st_widget_remove_style_pseudo_class (ST_WIDGET (entry), "indeterminate");
 
       priv->hint_visible = FALSE;
     }
@@ -845,7 +832,7 @@ st_entry_set_hint_text (StEntry     *entry,
       priv->hint_visible = TRUE;
 
       clutter_text_set_text (CLUTTER_TEXT (priv->entry), priv->hint);
-      st_widget_set_style_pseudo_class (ST_WIDGET (entry), "indeterminate");
+      st_widget_add_style_pseudo_class (ST_WIDGET (entry), "indeterminate");
     }
 }
 
index 3c6bbb7bc9de621d92de3bbf443d3b1024766e59..526432032775089dbf7b602ab9851b6ced307eb7 100644 (file)
@@ -723,7 +723,7 @@ handle_capture_event_cb (ClutterActor *trough,
                                                ((ClutterButtonEvent*) event)->y);
       if (target != bar->priv->handle)
         {
-          st_widget_set_style_pseudo_class ((StWidget*) bar->priv->handle, NULL);
+          st_widget_remove_style_pseudo_class ((StWidget*) bar->priv->handle, "hover");
         }
 
 
index ea4db0144124cd9ce5cd1f77af48c7eefe23518c..8a3b0340615aa3016ecf4c7f4639e210860c352d 100644 (file)
@@ -1354,34 +1354,165 @@ st_widget_get_theme (StWidget *actor)
   return actor->priv->theme;
 }
 
+static const gchar *
+find_class_name (const gchar *class_list,
+                 const gchar *class_name)
+{
+  gint len = strlen (class_name);
+  const gchar *match;
+
+  if (!class_list)
+    return NULL;
+
+  for (match = strstr (class_list, class_name); match; match = strstr (match + 1, class_name))
+    {
+      if ((match == class_list || g_ascii_isspace (match[-1])) &&
+          (match[len] == '\0' || g_ascii_isspace (match[len])))
+        return match;
+    }
+
+  return NULL;
+}
+
+static gboolean
+set_class_list (gchar       **class_list,
+                const gchar  *new_class_list)
+{
+  if (g_strcmp0 (*class_list, new_class_list) != 0)
+    {
+      g_free (*class_list);
+      *class_list = g_strdup (new_class_list);
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+static gboolean
+add_class_name (gchar       **class_list,
+                const gchar  *class_name)
+{
+  gchar *new_class_list;
+
+  if (*class_list)
+    {
+      if (find_class_name (*class_list, class_name))
+        return FALSE;
+
+      new_class_list = g_strdup_printf ("%s %s", *class_list, class_name);
+      g_free (*class_list);
+      *class_list = new_class_list;
+    }
+  else
+    *class_list = g_strdup (class_name);
+
+  return TRUE;
+}
+
+static gboolean
+remove_class_name (gchar       **class_list,
+                   const gchar  *class_name)
+{
+  const gchar *match, *end;
+  gchar *new_class_list;
+
+  if (!*class_list)
+    return FALSE;
+
+  if (strcmp (*class_list, class_name) == 0)
+    {
+      g_free (*class_list);
+      *class_list = NULL;
+      return TRUE;
+    }
+
+  match = find_class_name (*class_list, class_name);
+  if (!match)
+    return FALSE;
+  end = match + strlen (class_name);
+
+  /* Adjust either match or end to include a space as well.
+   * (One or the other must be possible at this point.)
+   */
+  if (match != *class_list)
+    match--;
+  else
+    end++;
+
+  new_class_list = g_strdup_printf ("%.*s%s", match - *class_list,
+                                    *class_list, end);
+  g_free (*class_list);
+  *class_list = new_class_list;
+
+  return TRUE;
+}
+
 /**
  * st_widget_set_style_class_name:
  * @actor: a #StWidget
- * @style_class: a new style class string
+ * @style_class_list: (allow-none): a new style class list string
  *
- * Set the style class name
+ * Set the style class name list. @style_class_list can either be
+ * %NULL, for no classes, or a space-separated list of style class
+ * names. See also st_widget_add_style_class_name() and
+ * st_widget_remove_style_class_name().
  */
 void
 st_widget_set_style_class_name (StWidget    *actor,
-                                const gchar *style_class)
+                                const gchar *style_class_list)
 {
-  StWidgetPrivate *priv = actor->priv;
-
   g_return_if_fail (ST_IS_WIDGET (actor));
 
-  priv = actor->priv;
-
-  if (g_strcmp0 (style_class, priv->style_class))
+  if (set_class_list (&actor->priv->style_class, style_class_list))
     {
-      g_free (priv->style_class);
-      priv->style_class = g_strdup (style_class);
-
       st_widget_style_changed (actor);
+      g_object_notify (G_OBJECT (actor), "style-class");
+    }
+}
+
+/**
+ * st_widget_add_style_class_name:
+ * @actor: a #StWidget
+ * @style_class: a style class name string
+ *
+ * Adds @style_class to @actor's style class name list, if it is not
+ * already present.
+ */
+void
+st_widget_add_style_class_name (StWidget    *actor,
+                                const gchar *style_class)
+{
+  g_return_if_fail (ST_IS_WIDGET (actor));
+  g_return_if_fail (style_class != NULL);
 
+  if (add_class_name (&actor->priv->style_class, style_class))
+    {
+      st_widget_style_changed (actor);
       g_object_notify (G_OBJECT (actor), "style-class");
     }
 }
 
+/**
+ * st_widget_remove_style_class_name:
+ * @actor: a #StWidget
+ * @style_class: a style class name string
+ *
+ * Removes @style_class from @actor's style class name, if it is
+ * present.
+ */
+void
+st_widget_remove_style_class_name (StWidget    *actor,
+                                   const gchar *style_class)
+{
+  g_return_if_fail (ST_IS_WIDGET (actor));
+  g_return_if_fail (style_class != NULL);
+
+  if (remove_class_name (&actor->priv->style_class, style_class))
+    {
+      st_widget_style_changed (actor);
+      g_object_notify (G_OBJECT (actor), "style-class");
+    }
+}
 
 /**
  * st_widget_get_style_class_name:
@@ -1400,14 +1531,37 @@ st_widget_get_style_class_name (StWidget *actor)
   return actor->priv->style_class;
 }
 
+/**
+ * st_widget_has_style_class_name:
+ * @actor: a #StWidget
+ * @style_class: a style class string
+ *
+ * Tests if @actor's style class list includes @style_class.
+ *
+ * Returns: whether or not @actor's style class list includes
+ * @style_class.
+ */
+gboolean
+st_widget_has_style_class_name (StWidget    *actor,
+                                const gchar *style_class)
+{
+  g_return_val_if_fail (ST_IS_WIDGET (actor), FALSE);
+
+  return find_class_name (actor->priv->style_class, style_class) != NULL;
+}
+
 /**
  * st_widget_get_style_pseudo_class:
  * @actor: a #StWidget
  *
- * Get the current style pseudo class
+ * Get the current style pseudo class list.
  *
- * Returns: the pseudo class string. The string is owned by the #StWidget and
- * should not be modified or freed.
+ * Note that an actor can have multiple pseudo classes; if you just
+ * want to test for the presence of a specific pseudo class, use
+ * st_widget_has_style_pseudo_class().
+ *
+ * Returns: the pseudo class list string. The string is owned by the
+ * #StWidget and should not be modified or freed.
  */
 const gchar*
 st_widget_get_style_pseudo_class (StWidget *actor)
@@ -1417,30 +1571,87 @@ st_widget_get_style_pseudo_class (StWidget *actor)
   return actor->priv->pseudo_class;
 }
 
+/**
+ * st_widget_has_style_pseudo_class:
+ * @actor: a #StWidget
+ * @pseudo_class: a pseudo class string
+ *
+ * Tests if @actor's pseudo class list includes @pseudo_class.
+ *
+ * Returns: whether or not @actor's pseudo class list includes
+ * @pseudo_class.
+ */
+gboolean
+st_widget_has_style_pseudo_class (StWidget    *actor,
+                                  const gchar *pseudo_class)
+{
+  g_return_val_if_fail (ST_IS_WIDGET (actor), FALSE);
+
+  return find_class_name (actor->priv->pseudo_class, pseudo_class) != NULL;
+}
+
 /**
  * st_widget_set_style_pseudo_class:
  * @actor: a #StWidget
- * @pseudo_class: (allow-none): a new pseudo class string
+ * @pseudo_class_list: (allow-none): a new pseudo class list string
  *
- * Set the style pseudo class
+ * Set the style pseudo class list. @pseudo_class_list can either be
+ * %NULL, for no classes, or a space-separated list of pseudo class
+ * names. See also st_widget_add_style_pseudo_class() and
+ * st_widget_remove_style_pseudo_class().
  */
 void
 st_widget_set_style_pseudo_class (StWidget    *actor,
-                                  const gchar *pseudo_class)
+                                  const gchar *pseudo_class_list)
 {
-  StWidgetPrivate *priv;
-
   g_return_if_fail (ST_IS_WIDGET (actor));
 
-  priv = actor->priv;
-
-  if (g_strcmp0 (pseudo_class, priv->pseudo_class))
+  if (set_class_list (&actor->priv->pseudo_class, pseudo_class_list))
     {
-      g_free (priv->pseudo_class);
-      priv->pseudo_class = g_strdup (pseudo_class);
+      st_widget_style_changed (actor);
+      g_object_notify (G_OBJECT (actor), "pseudo-class");
+    }
+}
 
+/**
+ * st_widget_add_style_pseudo_class:
+ * @actor: a #StWidget
+ * @pseudo_class: a pseudo class string
+ *
+ * Adds @pseudo_class to @actor's pseudo class list, if it is not
+ * already present.
+ */
+void
+st_widget_add_style_pseudo_class (StWidget    *actor,
+                                  const gchar *pseudo_class)
+{
+  g_return_if_fail (ST_IS_WIDGET (actor));
+  g_return_if_fail (pseudo_class != NULL);
+
+  if (add_class_name (&actor->priv->pseudo_class, pseudo_class))
+    {
       st_widget_style_changed (actor);
+      g_object_notify (G_OBJECT (actor), "pseudo-class");
+    }
+}
+
+/**
+ * st_widget_remove_style_pseudo_class:
+ * @actor: a #StWidget
+ * @pseudo_class: a pseudo class string
+ *
+ * Removes @pseudo_class from @actor's pseudo class, if it is present.
+ */
+void
+st_widget_remove_style_pseudo_class (StWidget    *actor,
+                                     const gchar *pseudo_class)
+{
+  g_return_if_fail (ST_IS_WIDGET (actor));
+  g_return_if_fail (pseudo_class != NULL);
 
+  if (remove_class_name (&actor->priv->pseudo_class, pseudo_class))
+    {
+      st_widget_style_changed (actor);
       g_object_notify (G_OBJECT (actor), "pseudo-class");
     }
 }
index bfe22320cfdbb1052db4777bd5592da2a7d82b9a..660c5e584f36b1c3ec0637fb76d624bef543e2ff 100644 (file)
@@ -84,11 +84,25 @@ struct _StWidgetClass
 GType st_widget_get_type (void) G_GNUC_CONST;
 
 void                  st_widget_set_style_pseudo_class    (StWidget        *actor,
+                                                           const gchar     *pseudo_class_list);
+void                  st_widget_add_style_pseudo_class    (StWidget        *actor,
+                                                           const gchar     *pseudo_class);
+void                  st_widget_remove_style_pseudo_class (StWidget        *actor,
                                                            const gchar     *pseudo_class);
 G_CONST_RETURN gchar *st_widget_get_style_pseudo_class    (StWidget        *actor);
+gboolean              st_widget_has_style_pseudo_class    (StWidget        *actor,
+                                                           const gchar     *pseudo_class);
+
 void                  st_widget_set_style_class_name      (StWidget        *actor,
+                                                           const gchar     *style_class_list);
+void                  st_widget_add_style_class_name      (StWidget        *actor,
+                                                           const gchar     *style_class);
+void                  st_widget_remove_style_class_name   (StWidget        *actor,
                                                            const gchar     *style_class);
 G_CONST_RETURN gchar *st_widget_get_style_class_name      (StWidget        *actor);
+gboolean              st_widget_has_style_class_name      (StWidget        *actor,
+                                                           const gchar     *style_class);
+
 void                  st_widget_set_style                 (StWidget        *actor,
                                                            const gchar     *style);
 G_CONST_RETURN gchar *st_widget_get_style                 (StWidget        *actor);
index f39471aef0d1d6aec8aee5086be0ff81aecc3bbc..425fc57734211c18ad93f5f8ec8cbccd766e430a 100644 (file)
@@ -3,9 +3,11 @@
 #include <clutter/clutter.h>
 #include "st-theme.h"
 #include "st-theme-context.h"
+#include "st-label.h"
 #include <math.h>
 #include <string.h>
 
+static ClutterActor *stage;
 static StThemeNode *root;
 static StThemeNode *group1;
 static StThemeNode *text1;
@@ -322,12 +324,72 @@ test_font (void)
 static void
 test_pseudo_class (void)
 {
+  StWidget *label;
+  StThemeNode *labelNode;
+
   test = "pseudo_class";
   /* text4 has :visited and :hover pseudo-classes, so should pick up both of these */
   assert_foreground_color (text4,   "text4",  0x888888ff);
   assert_text_decoration  (text4,   "text4",  ST_TEXT_DECORATION_UNDERLINE);
   /* :hover pseudo-class matches, but class doesn't match */
   assert_text_decoration  (group3,  "group3", 0);
+
+  /* Test the StWidget add/remove pseudo_class interfaces */
+  label = st_label_new ("foo");
+  clutter_container_add_actor (CLUTTER_CONTAINER (stage), CLUTTER_ACTOR (label));
+
+  labelNode = st_widget_get_theme_node (label);
+  assert_foreground_color (labelNode, "label", 0x000000ff);
+  assert_text_decoration  (labelNode, "label", 0);
+  assert_length ("label", "border-width", 0.,
+                 st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
+
+  st_widget_add_style_pseudo_class (label, "visited");
+  g_assert (st_widget_has_style_pseudo_class (label, "visited"));
+  labelNode = st_widget_get_theme_node (label);
+  assert_foreground_color (labelNode, "label", 0x888888ff);
+  assert_text_decoration  (labelNode, "label", 0);
+  assert_length ("label", "border-width", 0.,
+                 st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
+
+  st_widget_add_style_pseudo_class (label, "hover");
+  g_assert (st_widget_has_style_pseudo_class (label, "hover"));
+  labelNode = st_widget_get_theme_node (label);
+  assert_foreground_color (labelNode, "label", 0x888888ff);
+  assert_text_decoration  (labelNode, "label", ST_TEXT_DECORATION_UNDERLINE);
+  assert_length ("label", "border-width", 0.,
+                 st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
+
+  st_widget_remove_style_pseudo_class (label, "visited");
+  g_assert (!st_widget_has_style_pseudo_class (label, "visited"));
+  g_assert (st_widget_has_style_pseudo_class (label, "hover"));
+  labelNode = st_widget_get_theme_node (label);
+  assert_foreground_color (labelNode, "label", 0x000000ff);
+  assert_text_decoration  (labelNode, "label", ST_TEXT_DECORATION_UNDERLINE);
+  assert_length ("label", "border-width", 0.,
+                 st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
+
+  st_widget_add_style_pseudo_class (label, "boxed");
+  labelNode = st_widget_get_theme_node (label);
+  assert_foreground_color (labelNode, "label", 0x000000ff);
+  assert_text_decoration  (labelNode, "label", ST_TEXT_DECORATION_UNDERLINE);
+  assert_length ("label", "border-width", 1.,
+                 st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
+
+  st_widget_remove_style_pseudo_class (label, "hover");
+  labelNode = st_widget_get_theme_node (label);
+  assert_foreground_color (labelNode, "label", 0x000000ff);
+  assert_text_decoration  (labelNode, "label", 0);
+  assert_length ("label", "border-width", 1.,
+                 st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
+
+  st_widget_remove_style_pseudo_class (label, "boxed");
+  g_assert (st_widget_get_style_pseudo_class (label) == NULL);
+  labelNode = st_widget_get_theme_node (label);
+  assert_foreground_color (labelNode, "label", 0x000000ff);
+  assert_text_decoration  (labelNode, "label", 0);
+  assert_length ("label", "border-width", 0.,
+                 st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
 }
 
 static void
@@ -351,7 +413,8 @@ main (int argc, char **argv)
   theme = st_theme_new ("st/test-theme.css",
                         NULL, NULL);
 
-  context = st_theme_context_new ();
+  stage = clutter_stage_get_default ();
+  context = st_theme_context_get_for_stage (CLUTTER_STAGE (stage));
   st_theme_context_set_theme (context, theme);
   st_theme_context_set_resolution (context, 96.);
   st_theme_context_set_font (context,
index b2fad3699c13886d629b69ba81e3f084ab5fc511..77ae34c1981c1541f2403943ec6c3a47d1bb9a7d 100644 (file)
@@ -64,10 +64,14 @@ stage > #text2 {
     border-radius: 10px 10px 0px 0px;
 }
 
-ClutterText:hover {
+ClutterText:hover, StLabel:hover {
     text-decoration: underline;
 }
 
-ClutterText:visited {
+ClutterText:visited, StLabel:visited {
     color: #888888;
 }
+
+StLabel:boxed {
+    border: 1px;
+}